package tr.edu.ege.seagent.hobnobwebapp;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import tr.edu.ege.seagent.hobnobontology.instance.HobNobResultSetSolution;
import tr.edu.ege.seagent.hobnobontology.instance.HobNobSPARQLQueries;

/**
 * Servlet implementation class HobNobFindLocationOfNotification
 */
@WebServlet("/HobNobLocation")
public class HobNobFindLocationOfNotification extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * Processes the servlet request. This method retieves a parameter named
	 * <i>resourceURI</i> from the request and executes LinkedGeoData query for
	 * it. Then constructs an HTML to list the place results in a table.
	 * 
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		PrintWriter out = response.getWriter();
		// Getting resourceURI as a parameter...
		String resourceURI = request.getParameter("resourceURI");

		// find linkedgeodata locations...
		HobNobSPARQLQueries query = new HobNobSPARQLQueries();
		List<HobNobResultSetSolution> resultSet = query
				.findLocationOfNotificationOverHttp(resourceURI);

		// construct response HTML...
		startHTML(request, response, out);
		startTable(out);

		// get place list...
		List<String> placeURIList = getPlaces(resultSet);
		// write places to table rows...
		for (String placeURI : placeURIList) {
			List<HobNobResultSetSolution> placeResults = getPlaceResults(
					resultSet, placeURI);
			writePlace(request, out, placeURI, placeResults);
		}

		// close table...
		out.print("</table>");

		// close body...
		out.print("</body>");
	}

	/**
	 * Starts the HTML body and puts an image to the background.
	 * 
	 * @param request
	 *            HTTP request.
	 * @param response
	 *            HTTP response.
	 * @param out
	 *            writer.
	 */
	private void startHTML(HttpServletRequest request,
			HttpServletResponse response, PrintWriter out) {
		// response.setContentType("image/jpeg");
		response.setContentType("text/html");
		out.print("<body background ='" + request.getContextPath()
				+ "/images/map.jpg'>");
		out.print("<center>");
		out.print("<span style='font-size: 250%; afont-weight:bold; color:#999; margin-left:40px'>HobNob <span style='font-weight:bold'>Web Application</span></span>");
		out.print("</center>");
		out.print("<br>");
	}

	/**
	 * Writes the headers of the HTML table.
	 * 
	 * @param out
	 *            writer.
	 */
	private void startTable(PrintWriter out) {
		out.print("<table border=\"5\">");
		out.print("<tr>");
		out.print("<th>");
		out.print("Location");
		out.print("</th>");
		out.print("<th>");
		out.print("Latitude");
		out.print("</th>");
		out.print("<th>");
		out.print("Longitude");
		out.print("</th>");
		out.print("<th>");
		out.print("Location Type");
		out.print("</th>");
		out.print("</tr>");
	}

	/**
	 * Retrieves the solution list of given place.
	 * 
	 * @param resultSet
	 *            result list of linkedgeodata query.
	 * @param placeURI
	 *            URI of the place which is desired to find related solutions.
	 * @return list of solutions whose location is the given place.
	 */
	private List<HobNobResultSetSolution> getPlaceResults(
			List<HobNobResultSetSolution> resultSet, String placeURI) {
		List<HobNobResultSetSolution> placeResults = new ArrayList<HobNobResultSetSolution>();
		for (HobNobResultSetSolution result : resultSet) {
			if (placeURI.equals(result.getLocation().asResource().getURI())) {
				placeResults.add(result);
			}
		}
		return placeResults;
	}

	/**
	 * Constructs a table row for the given place.
	 * 
	 * @param out
	 *            writer.
	 * @param placeURI
	 *            place which is desired to be written to HTML table.
	 * @param placeResults
	 *            list of solutions about place.
	 */
	private void writePlace(HttpServletRequest request, PrintWriter out, String placeURI,
			List<HobNobResultSetSolution> placeResults) {
		// get first result to write common properties...
		HobNobResultSetSolution firstResult = placeResults.get(0);
		// write common properties...
		out.print("<tr>");
		out.print("<td>");
		out.print("<img src='" + request.getContextPath()
				+ "/images/location.png'/> ");
		out.print("<a href=\"" + firstResult.getLocation() + "\">"
				+ firstResult.getLabel().asLiteral().getString() + "</a>");
		out.print("</td>");
		out.print("<td>");
		out.print(Double.toString(firstResult.getxCoordinate().asLiteral()
				.getDouble()));
		out.print("</td>");
		out.print("<td>");
		out.print(Double.toString(firstResult.getyCoordinate().asLiteral()
				.getDouble()));
		out.print("</td>");
		out.print("<td>");
		// write all types of the place from solution list...
		for (HobNobResultSetSolution subResult : placeResults) {
			out.print(subResult.getType().asResource().getURI().replace("http://linkedgeodata.org/ontology/", "" )  + "<br>");
		}
		// close table row...
		out.print("</td>");
		out.print("</tr>");
	}

	/**
	 * Traverses the given result set and collects place URIs.
	 * 
	 * @param resultSet
	 *            result of the linkedgeodata place query.
	 * @return a list of place URIs which are not repeated.
	 */
	private List<String> getPlaces(List<HobNobResultSetSolution> resultSet) {
		List<String> placeURIList = new ArrayList<String>();
		for (HobNobResultSetSolution result : resultSet) {
			String placeURI = result.getLocation().asResource().getURI();
			if (!placeURIList.contains(placeURI)) {
				placeURIList.add(placeURI);
			}
		}
		return placeURIList;
	}

}
